#pragma once

#include <vector>
#include "graph/Surface.h"

typedef HDC vSysDC;

class Tracker
{
public:
	virtual ~Tracker(){delete m_pen;}
	void SetSize(const Size& size){m_size = size;}
	const Point& BeginPoint() const {return m_begin;}
	const Point& EndPoint() const {return m_end;}
	void CalcFRect(Rect& firstRect,Rect& lastrect)
	{
		firstRect = Rect(m_begin,m_preend);
		lastrect = Rect(m_begin,m_end);
	}

	virtual void Draw() = 0;
	virtual void Track(Graphics* graphics,const Point& point)
	{
		this->graphics = graphics;
		m_begin = m_end = m_preend = point;
	}
	virtual void Tracking(const Point& point)
	{
		m_preend = m_end;
		m_end = point;

		const float NODE_SIZE = graphics->UnitMMtoLine(m_size.cx);
		Rect firstrect,lastrect;
		CalcFRect(firstrect,lastrect);
		firstrect += Size(NODE_SIZE,NODE_SIZE);
		lastrect += Size(NODE_SIZE,NODE_SIZE);
		//if (lastrect>=firstrect)
		//	m_view->Refresh(lastrect);
		//else
		//	m_view->Refresh(firstrect);
		Draw();
	}
	vSysDC GetDC() const
	{
		DeviceSurface* ds = (DeviceSurface*)graphics->GetGraphicsSurface();
		return (vSysDC)ds->deviceContext;
	}

protected:
	Tracker()
	{
		m_pen = new Pen(Color::RoyalBlue);
		m_size = Size(1.0f,1.0f);
		graphics = NULL;
	}

	Graphics* graphics;
	IView* m_view;
	Pen* m_pen;
	Size m_size;
	Point m_begin;
	Point m_end;
	Point m_preend;
};

typedef std::vector<Tracker*> Trackers;

class LineTracker : public Tracker
{
public:
	virtual void Draw()
	{
		if (!graphics)	return;

		Rect firstrect,lastrect;
		CalcFRect(firstrect,lastrect);

		const float NODE_SIZE = graphics->UnitMMtoLine(m_size.cx);
		const float NODE_SIZE_HALF = NODE_SIZE/2;

		Point begin = lastrect.LeftTop();
		Point end = lastrect.RightBottom();
		float width = lastrect.Width();
		float height = lastrect.Height();

		Point node1_1(begin.x-NODE_SIZE_HALF,begin.y-NODE_SIZE_HALF);
		Point node3_3(begin.x+width-NODE_SIZE_HALF,begin.y+height-NODE_SIZE_HALF);

		graphics->DrawRectangle(*m_pen,node1_1.x,node1_1.y,NODE_SIZE,NODE_SIZE);
		graphics->DrawRectangle(*m_pen,node3_3.x,node3_3.y,NODE_SIZE,NODE_SIZE);

		graphics->DrawLine(*m_pen,begin,end);
	}
};

class RectTracker : public Tracker
{
public:
	virtual void Draw()
	{
		if (!graphics)	return;

		Rect firstrect,lastrect;
		CalcFRect(firstrect,lastrect);

		const float NODE_SIZE = graphics->UnitMMtoLine(m_size.cx);
		const float NODE_SIZE_HALF = NODE_SIZE/2;

		Point begin = lastrect.LeftTop();
		Point end = lastrect.RightBottom();
		float width = lastrect.Width();
		float height = lastrect.Height();

		Point node1_1(begin.x-NODE_SIZE_HALF,begin.y-NODE_SIZE_HALF);
		Point node1_2(begin.x+width/2-NODE_SIZE_HALF,begin.y-NODE_SIZE_HALF);
		Point node1_3(begin.x+width-NODE_SIZE_HALF,begin.y-NODE_SIZE_HALF);

		Point node2_1(begin.x-NODE_SIZE_HALF,begin.y+height/2-NODE_SIZE_HALF);
		Point node2_2(begin.x+width/2-NODE_SIZE_HALF,begin.y+height/2-NODE_SIZE_HALF);
		Point node2_3(begin.x+width-NODE_SIZE_HALF,begin.y+height/2-NODE_SIZE_HALF);

		Point node3_1(begin.x-NODE_SIZE_HALF,begin.y+height-NODE_SIZE_HALF);
		Point node3_2(begin.x+width/2-NODE_SIZE_HALF,begin.y+height-NODE_SIZE_HALF);
		Point node3_3(begin.x+width-NODE_SIZE_HALF,begin.y+height-NODE_SIZE_HALF);

		const Point& center = node2_2;

		graphics->DrawRectangle(*m_pen,begin.x,begin.y,width,height);

		graphics->DrawRectangle(*m_pen,node1_1.x,node1_1.y,NODE_SIZE,NODE_SIZE);
		graphics->DrawRectangle(*m_pen,node1_2.x,node1_2.y,NODE_SIZE,NODE_SIZE);
		graphics->DrawRectangle(*m_pen,node1_3.x,node1_3.y,NODE_SIZE,NODE_SIZE);

		graphics->DrawRectangle(*m_pen,node2_1.x,node2_1.y,NODE_SIZE,NODE_SIZE);
		graphics->DrawRectangle(*m_pen,node2_2.x,node2_2.y,NODE_SIZE,NODE_SIZE);
		graphics->DrawRectangle(*m_pen,node2_3.x,node2_3.y,NODE_SIZE,NODE_SIZE);

		graphics->DrawRectangle(*m_pen,node3_1.x,node3_1.y,NODE_SIZE,NODE_SIZE);
		graphics->DrawRectangle(*m_pen,node3_2.x,node3_2.y,NODE_SIZE,NODE_SIZE);
		graphics->DrawRectangle(*m_pen,node3_3.x,node3_3.y,NODE_SIZE,NODE_SIZE);

		graphics->FillRectangle(m_pen->GetBrush(),node2_2.x,node2_2.y,NODE_SIZE,NODE_SIZE);
	}
};

#ifdef _WINDOWS_
#include <GdiPlus.h>
#pragma comment(lib,"gdiplus.lib")
class GdiplusUtil
{
public:
	static GdiplusUtil* Instance() {static GdiplusUtil instance; return &instance;}

	bool Open()
	{
		Gdiplus::GdiplusStartupInput input;
		return Gdiplus::GdiplusStartup(&m_token, &input, NULL)==Gdiplus::Ok;
	}
	void Close()
	{
		Gdiplus::GdiplusShutdown(m_token);
	}

private:
	ULONG_PTR m_token;
};
#endif